From 985d2d221c6b34293cc2aff4f51b745f7680340e Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 1 Oct 2021 08:48:43 -0400 Subject: [PATCH] ngl: Determine intermediate formats Look at the framebuffer and the rendernode to determine what format to use for intermediate textures. Our preference here is to use fp16, if we have it and it makes sense for the framebuffer we're given. --- gsk/ngl/gsknglrenderjob.c | 44 +++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c index d285eb24b0..e3436e10f4 100644 --- a/gsk/ngl/gsknglrenderjob.c +++ b/gsk/ngl/gsknglrenderjob.c @@ -162,6 +162,11 @@ struct _GskNglRenderJob /* If we should be rendering red zones over fallback nodes */ guint debug_fallback : 1; + + /* Format we want to use for intermediate textures, determined by + * looking at the format of the framebuffer we are rendering on. + */ + int target_format; }; typedef struct _GskNglRenderOffscreen @@ -198,6 +203,16 @@ static gboolean gsk_ngl_render_job_visit_node_with_offscreen (GskNglRenderJob const GskRenderNode *node, GskNglRenderOffscreen *offscreen); +static inline int +get_target_format (GskNglRenderJob *job, + const GskRenderNode *node) +{ + if (gsk_render_node_prefers_high_depth (node)) + return job->target_format; + + return GL_RGBA8; +} + static inline void init_full_texture_region (GskNglRenderOffscreen *offscreen) { @@ -1258,7 +1273,7 @@ blur_offscreen (GskNglRenderJob *job, if (!gsk_ngl_driver_create_render_target (job->driver, MAX (texture_to_blur_width, 1), MAX (texture_to_blur_height, 1), - GL_RGBA8, + job->target_format, GL_NEAREST, GL_NEAREST, &pass1)) return 0; @@ -1269,7 +1284,7 @@ blur_offscreen (GskNglRenderJob *job, if (!gsk_ngl_driver_create_render_target (job->driver, texture_to_blur_width, texture_to_blur_height, - GL_RGBA8, + job->target_format, GL_NEAREST, GL_NEAREST, &pass2)) return gsk_ngl_driver_release_render_target (job->driver, pass1, FALSE); @@ -2181,7 +2196,7 @@ gsk_ngl_render_job_visit_blurred_inset_shadow_node (GskNglRenderJob *job, if (!gsk_ngl_driver_create_render_target (job->driver, texture_width, texture_height, - GL_RGBA8, + get_target_format (job, node), GL_NEAREST, GL_NEAREST, &render_target)) g_assert_not_reached (); @@ -2452,7 +2467,7 @@ gsk_ngl_render_job_visit_blurred_outset_shadow_node (GskNglRenderJob *job, gsk_ngl_driver_create_render_target (job->driver, texture_width, texture_height, - GL_RGBA8, + get_target_format (job, node), GL_NEAREST, GL_NEAREST, &render_target); @@ -3860,7 +3875,7 @@ gsk_ngl_render_job_visit_node_with_offscreen (GskNglRenderJob *job, if (!gsk_ngl_driver_create_render_target (job->driver, scaled_width, scaled_height, - GL_RGBA8, + get_target_format (job, node), filter, filter, &render_target)) g_assert_not_reached (); @@ -3959,7 +3974,7 @@ gsk_ngl_render_job_render_flipped (GskNglRenderJob *job, if (!gsk_ngl_command_queue_create_render_target (job->command_queue, MAX (1, job->viewport.size.width), MAX (1, job->viewport.size.height), - GL_RGBA8, + job->target_format, GL_NEAREST, GL_NEAREST, &framebuffer_id, &texture_id)) return; @@ -4050,6 +4065,22 @@ gsk_ngl_render_job_set_debug_fallback (GskNglRenderJob *job, job->debug_fallback = !!debug_fallback; } +static int +get_framebuffer_format (guint framebuffer) +{ + int size; + + glBindFramebuffer (GL_FRAMEBUFFER, framebuffer); + glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, &size); + + if (size >= 32) + return GL_RGBA32F; + else if (size >= 16) + return GL_RGBA16F; + else + return GL_RGBA8; +} + GskNglRenderJob * gsk_ngl_render_job_new (GskNglDriver *driver, const graphene_rect_t *viewport, @@ -4076,6 +4107,7 @@ gsk_ngl_render_job_new (GskNglDriver *driver, job->scale_x = scale_factor; job->scale_y = scale_factor; job->viewport = *viewport; + job->target_format = get_framebuffer_format (framebuffer); gsk_ngl_render_job_set_alpha (job, 1.0f); gsk_ngl_render_job_set_projection_from_rect (job, viewport, NULL); -- 2.30.2